package own.stu.jobgib.playown.juc;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.*;

public class DelayQueueTest {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        DelayQueue<MyDelay> queue = new DelayQueue();

        queue.add(new MyDelay(60 * 1000, "第一次添加任务"));
        queue.add(new MyDelay(120 * 1000, "第二次添加任务"));
        queue.add(new MyDelay(240 * 1000, "第三次添加任务"));


        executorService.submit(() -> {
            try {
                queue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        executorService.submit(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
                queue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        executorService.awaitTermination(1, TimeUnit.HOURS);
    }

    static class MyDelay<T> implements Delayed {


        long delayTime; // 延迟时间
        long expire; // 过期时间
        T data;

        public MyDelay(long delayTime, T t) {
            this.delayTime = delayTime;
            // 过期时间 = 当前时间 + 延迟时间
            this.expire = System.currentTimeMillis() + delayTime;
            data = t;
        }

        /**
         * 剩余时间 = 到期时间 - 当前时间
         */
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        /**
         * 优先级规则：两个任务比较，时间短的优先执行
         */
        @Override
        public int compareTo(Delayed o) {
            long f = this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS);
            return (int) f;
        }


        @Override
        public String toString() {
            return "delayTime=" + delayTime +
                    ", expire=" + expire +
                    ", data=" + data;
        }
    }
}
